package com.newviews.tcmip.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.newviews.tcmip.common.constant.CombinConsts;
import com.newviews.tcmip.common.constant.CommonConsts;
import com.newviews.tcmip.common.enums.UiElCodeEnums;
import com.newviews.tcmip.common.model.PageModel;
import com.newviews.tcmip.common.model.ResultModel;
import com.newviews.tcmip.dao.*;
import com.newviews.tcmip.pojo.po.*;
import com.newviews.tcmip.pojo.vo.EtcmCommonBaseInfoRespVO;
import com.newviews.tcmip.pojo.vo.index.EtcmIndexStatusticsRespVO;
import com.newviews.tcmip.service.inf.*;
import com.newviews.tcmip.web.vo.etcmingr.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.io.PrintStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 中草药库 服务实现类
 * </p>
 *
 * @author lxc
 * @since 2024-02-29
 */
@Service
public class EtcmIngrServiceImpl extends ServiceImpl<EtcmIngrMapper, EtcmIngrPo> implements EtcmIngrServiceInf {
    @Resource
    private EtcmIngrExServiceInf etcmIngrExServiceInf;
    @Resource
    private EtcmTargetExServiceInf etcmTargetExServiceInf;
    @Resource
    private EtcmIngrExMapper etcmIngrExMapper;
    @Resource
    private EtcmHerbExMapper etcmHerbExMapper;
    @Resource
    private EtcmExperimentalRecordsExServiceInf etcmExperimentalRecordsExServiceInf;
    @Resource
    private EtcmPxExMapper etcmPxExMapper;
    @Resource
    private EtcmPxExServiceInf etcmPxExServiceInf;

    @Override
    public ResultModel<EtcmIndexStatusticsRespVO> getStatisticsIngr(String langCode, String uiTypeCode, String prepositionContent) {
        EtcmIndexStatusticsRespVO vo = new EtcmIndexStatusticsRespVO();

        QueryWrapper<EtcmIngrPo> wrapper = new QueryWrapper<>();

        if (StringUtils.isNotBlank(prepositionContent)) {
            wrapper.and(w->w.like( "ingr_zh_name", prepositionContent)
                    .or().like( "ingr_zh_name_py", prepositionContent)
                    .or().like( "ingr_zh_name_wb", prepositionContent)
                    .or().like( "ingr_zh_name_abb", prepositionContent)
                    .or().like( "ingr_en_name", prepositionContent)
                    .or().like( "ingr_en_name_abb", prepositionContent)
                    .or().like( "ingr_latin_name", prepositionContent)
                    .or().like( "ingr_latin_name_abb", prepositionContent)
                    .or().like( "ingr_name_alias", prepositionContent)
            );
        }


        wrapper.eq("status", CommonConsts.COMMON_YES);


        int count = this.count(wrapper);

        vo.setIngredients(count);
        return new ResultModel<EtcmIndexStatusticsRespVO>().success(vo);
    }
    @Override
    public ResultModel<PageModel<Map<String, String>>> getIndexPage(String languageCode, String uiTypeCode, Integer pageNo, Integer pageSize, String searchName, String sortType,String pConent) {
        QueryWrapper<EtcmIngrPo> wrapper = new QueryWrapper<>();

        if (StringUtils.isNotBlank(searchName)) {
            wrapper.and(w -> w.like("ingr_zh_name", searchName)
                    .or().like("ingr_zh_name_abb", searchName)
                    .or().like("ingr_zh_name_wb", searchName)
                    .or().like("ingr_zh_name_py", searchName)
                    .or().like("ingr_en_name", searchName)
                    .or().like("ingr_en_name_abb", searchName)
                    .or().like("ingr_latin_name", searchName)
                    .or().like("ingr_latin_name_abb", searchName)
                    .or().like("ingr_name_alias", searchName));
        }
        if (StringUtils.isNotBlank(pConent)) {
            wrapper.and(w -> w.like("ingr_zh_name", pConent)
                    .or().like("ingr_zh_name_abb", pConent)
                    .or().like("ingr_zh_name_wb", pConent)
                    .or().like("ingr_zh_name_py", pConent)
                    .or().like("ingr_en_name", pConent)
                    .or().like("ingr_en_name_abb", pConent)
                    .or().like("ingr_latin_name", pConent)
                    .or().like("ingr_latin_name_abb", pConent)
                    .or().like("ingr_name_alias", pConent));
        }

        wrapper.eq("status", CommonConsts.COMMON_YES);
        wrapper.groupBy("id");
        if (sortType.equalsIgnoreCase(CommonConsts.SORT_TYPE_ASC)) {
            wrapper.orderByAsc("id");
        } else {
            wrapper.orderByDesc("id");
        }

        IPage<EtcmIngrPo> page = this.page(new Page<>(pageNo, pageSize), wrapper);
        List<EtcmIngrExPo> exList = etcmIngrExServiceInf.list(new QueryWrapper<EtcmIngrExPo>()
                .eq("status", CommonConsts.COMMON_YES)
                .eq("language_code", languageCode)
                .eq("ui_type_code", uiTypeCode)
        );

        List<Map<String, String>> resList = new ArrayList<>();
        for (EtcmIngrPo record : page.getRecords()) {
            HashMap<String, String> map = new HashMap<>();
            for (EtcmIngrExPo etcmIngrExPo : exList) {
                if (etcmIngrExPo.getIngrId().equals(record.getIngrCode())) {
                    map.put(etcmIngrExPo.getUiElCode(), etcmIngrExPo.getIngrExCon());
                }
            }

            resList.add(map);
        }
        PageModel<Map<String, String>> resPage = new PageModel<>();
        resPage.setPageNo(pageNo);
        resPage.setPageSize(pageSize);
        resPage.setRecords(resList);
        resPage.setTotalCount(page.getTotal());
        return new ResultModel<PageModel<Map<String, String>>>().success(resPage);
    }

    @Override
    public List<Map<String, String>> getIngrDownload(EtcmIngrExportReqVO reqVO) {
        QueryWrapper<EtcmIngrPo> wrapper = new QueryWrapper<>();

        if (StringUtils.isNotBlank(reqVO.getContent())) {
            wrapper.and(w -> w.like("ingr_zh_name", reqVO.getContent())
                    .or().like("ingr_zh_name_abb", reqVO.getContent())
                    .or().like("ingr_zh_name_wb", reqVO.getContent())
                    .or().like("ingr_zh_name_py", reqVO.getContent())
                    .or().like("ingr_en_name", reqVO.getContent())
                    .or().like("ingr_en_name_abb", reqVO.getContent())
                    .or().like("ingr_latin_name", reqVO.getContent())
                    .or().like("ingr_latin_name_abb", reqVO.getContent())
                    .or().like("ingr_name_alias", reqVO.getContent()));
        }
        if (StringUtils.isNotBlank(reqVO.getPrepositionContent())) {
            wrapper.and(w -> w.like("ingr_zh_name", reqVO.getPrepositionContent())
                    .or().like("ingr_zh_name_abb", reqVO.getPrepositionContent())
                    .or().like("ingr_zh_name_wb", reqVO.getPrepositionContent())
                    .or().like("ingr_zh_name_py", reqVO.getPrepositionContent())
                    .or().like("ingr_en_name", reqVO.getPrepositionContent())
                    .or().like("ingr_en_name_abb", reqVO.getPrepositionContent())
                    .or().like("ingr_latin_name", reqVO.getPrepositionContent())
                    .or().like("ingr_latin_name_abb", reqVO.getPrepositionContent())
                    .or().like("ingr_name_alias", reqVO.getPrepositionContent()));
        }

        wrapper.eq("status", CommonConsts.COMMON_YES);
        wrapper.groupBy("id");
        if (reqVO.getSortType().equalsIgnoreCase(CommonConsts.SORT_TYPE_ASC)) {
            wrapper.orderByAsc("id");
        } else {
            wrapper.orderByDesc("id");
        }

        List<EtcmIngrPo> page = this.list(wrapper);
        List<EtcmIngrExPo> exList = etcmIngrExServiceInf.list(new QueryWrapper<EtcmIngrExPo>()
                .eq("status", CommonConsts.COMMON_YES)
                .eq("language_code", reqVO.getLangCode())
                .eq("ui_type_code", reqVO.getUiTypeCode())
        );

        Map<String,List<EtcmIngrExPo>> disMap = new HashMap<>(16);
        for (EtcmIngrPo record : page) {
            List<EtcmIngrExPo> disList = new ArrayList<>();
            for (EtcmIngrExPo etcmIngrExPo : exList) {
                if (etcmIngrExPo.getIngrId().equals(record.getIngrCode())) {
                    disList.add(etcmIngrExPo);
                }
            }

            disMap.put(record.getIngrCode(), disList);
        }
        List<EtcmUiElPo> etcmUiElPos = etcmPxExMapper.getUIElName(reqVO.getUiTypeCode(),reqVO.getLangCode());
        List<Map<String, String>> resultList = new ArrayList<>();

        for (String key : disMap.keySet()) {
            Map<String,String> mapRes=new HashMap<>(16);
            List<EtcmIngrExPo> values = disMap.get(key);
            List<String> collect = values.stream().map(EtcmIngrExPo::getUiElCode).collect(Collectors.toList());
            for (EtcmUiElPo etcmUiElPo : etcmUiElPos) {
                if (collect.contains(etcmUiElPo.getUiElCode())){
                    for (EtcmIngrExPo EtcmIngrExPo : values) {
                        if (etcmUiElPo.getUiElCode().equals(EtcmIngrExPo.getUiElCode())){
                            mapRes.put(EtcmIngrExPo.getUiElCode(), EtcmIngrExPo.getIngrExCon());
                        }
                    }
                }else {
                    mapRes.put(etcmUiElPo.getUiElCode(), "");
                }

            }

            resultList.add(mapRes);
        }
        return resultList;
    }




    @Override
    public ResultModel<PageModel<Map<String, String>>> getPageByExperimentalRecords(String languageCode, String uiTypeCode, String ingrId, Integer pageNo, Integer pageSize, String searchName,String sortType) {
        QueryWrapper<EtcmExperimentalRecordsPo> wrapper = new QueryWrapper<>();
        wrapper.eq("t1.ingr_id",ingrId);

        if(com.newviews.tcmip.common.utils.StringUtils.isNotBlank(searchName)){
            wrapper.and(w->w.like("t2.er_zh_name", searchName)
                    .or().like("t2.er_zh_name_py", searchName)
                    .or().like("t2.er_zh_name_wb", searchName)
                    .or().like("t2.er_zh_name_abb", searchName)
                    .or().like("t2.er_en_name", searchName)
                    .or().like("t2.er_en_name_abb", searchName)
                    .or().like("t2.er_latin_name", searchName)
                    .or().like("t2.er_latin_name_abb", searchName)
                    .or().like("t2.er_name_alias", searchName));
        }
        if(sortType.equalsIgnoreCase(CommonConsts.SORT_TYPE_ASC)){
            wrapper.orderByAsc("t1.er_id");
        }else {
            wrapper.orderByDesc("t1.er_id");
        }
        IPage<EtcmExperimentalRecordsIngrPo> pageEr = etcmIngrExMapper.getPageEr(new Page(pageNo, pageSize), wrapper);
        List<Map<String,String>> resultList=new ArrayList<>();

        List<EtcmUiElPo> uiElName = etcmPxExMapper.getUIElName(uiTypeCode, languageCode);
        for (EtcmExperimentalRecordsIngrPo record : pageEr.getRecords()) {
            Map<String, String> map = getStringStringMap(languageCode, record, uiElName);
            resultList.add(map);
        }

        PageModel<Map<String,String>> page=new PageModel<>();
        page.setPageNo(pageNo);
        page.setPageSize(pageSize);
        page.setRecords(resultList);
        page.setTotalCount(pageEr.getTotal());
        return new ResultModel<PageModel<Map<String,String>>>().success(page);
    }

    @Override
    public ResultModel<PageModel<Map<String, String>>> getPageBySynergisticIngredients(String languageCode, String uiTypeCode, String ingrId, Integer pageNo, Integer pageSize, String searchName,String sortType) {
        QueryWrapper<EtcmIngrIngrPo> wrapper=new QueryWrapper<>();
        if(com.newviews.tcmip.common.utils.StringUtils.isNotBlank(searchName)){
            wrapper.and(w -> w.like("t1.ingr_zh_name",searchName)
                    .or().like("t1.ingr_zh_name_abb", searchName)
                    .or().like("t1.ingr_zh_name_wb", searchName)
                    .or().like("t1.ingr_zh_name_py",searchName)
                    .or().like("t1.ingr_en_name", searchName)
                    .or().like("t1.ingr_en_name_abb", searchName)
                    .or().like("t1.ingr_latin_name", searchName)
                    .or().like("t1.ingr_latin_name_abb", searchName)
                    .or().like("t1.ingr_name_alias", searchName)

                    .or().like("t3.ingr_zh_name",searchName)
                    .or().like("t3.ingr_zh_name_abb", searchName)
                    .or().like("t3.ingr_zh_name_wb", searchName)
                    .or().like("t3.ingr_zh_name_py",searchName)
                    .or().like("t3.ingr_en_name", searchName)
                    .or().like("t3.ingr_en_name_abb", searchName)
                    .or().like("t3.ingr_latin_name", searchName)
                    .or().like("t3.ingr_latin_name_abb", searchName)
                    .or().like("t3.ingr_name_alias", searchName)
            );
        }
        wrapper.eq("t1.ingr_code", ingrId);
        //wrapper.orderByAsc("t2.ingr_ingr_distance");
        wrapper.isNotNull("t2.ingr_ingr_distance");
        wrapper.gt("t2.ingr_ingr_distance",0);
        wrapper.last("limit 200");


        List<EtcmIngrIngrPo> iPage=etcmIngrExMapper.getPageBySynergisticIngredients( wrapper);
        List<EtcmUiElPo> uiElName = etcmPxExMapper.getUIElName(uiTypeCode, languageCode);
        List<Map<String,String>> resultList=new ArrayList<>();

        if(sortType.equalsIgnoreCase(CommonConsts.SORT_TYPE_ASC)){
            iPage = iPage.stream().sorted(Comparator.comparing(EtcmIngrIngrPo::getIngrIngrDistance)).collect(Collectors.toList());
        }else {
            iPage = iPage.stream().sorted(Comparator.comparing(EtcmIngrIngrPo::getIngrIngrDistance).reversed()).collect(Collectors.toList());
        }
        List<EtcmIngrIngrPo> collect = iPage.stream().skip((pageNo - 1) * pageSize).limit(pageSize).
                collect(Collectors.toList());
        collect.forEach(etcmIngrIngrPo -> {
            Map<String, String> map = getStringStringMap(languageCode, etcmIngrIngrPo, uiElName);
            resultList.add(map);
        });
        PageModel<Map<String,String>> page=new PageModel<>();
        page.setPageNo(pageNo);
        page.setPageSize(pageSize);
        page.setRecords(resultList);
        page.setTotalCount(iPage.size());
        return new ResultModel<PageModel<Map<String,String>>>().success(page);
    }

    @Override
    public ResultModel<PageModel<Map<String, String>>> getPageByAssociatedDiseases(String languageCode, String uiTypeCode, String ingrId, Integer pageNo, Integer pageSize, String searchName,String sortType) {
        QueryWrapper<EtcmIngrDiseasePo> wrapper=new QueryWrapper<>();
        if(com.newviews.tcmip.common.utils.StringUtils.isNotBlank(searchName)){
            wrapper.and(w -> w.like("A.ingr_zh_name",searchName)
                    .or().like("A.ingr_zh_name_abb", searchName)
                    .or().like("A.ingr_zh_name_wb", searchName)
                    .or().like("A.ingr_zh_name_py",searchName)
                    .or().like("A.ingr_en_name", searchName)
                    .or().like("A.ingr_en_name_abb", searchName)
                    .or().like("A.ingr_latin_name", searchName)
                    .or().like("A.ingr_latin_name_abb", searchName)
                    .or().like("A.ingr_name_alias", searchName)

                    .or().like("B.disease_zh_name",searchName)
                    .or().like("B.disease_zh_name_abb", searchName)
                    .or().like("B.disease_zh_name_wb", searchName)
                    .or().like("B.disease_zh_name_py",searchName)
                    .or().like("B.disease_en_name", searchName)
                    .or().like("B.disease_en_name_abb", searchName)
                    .or().like("B.disease_latin_name", searchName)
                    .or().like("B.disease_latin_name_abb", searchName)
                    .or().like("B.disease_name_alias", searchName)
            );
        }
        wrapper.eq("C.ingr_id", ingrId);
        wrapper.orderByAsc("C.ingr_disease_distance");
//        wrapper.isNotNull("C.ingr_disease_distance");
//        wrapper.gt("C.ingr_disease_distance",0);
        wrapper.last("limit 200");


        List<EtcmIngrDiseasePo> iPage=etcmIngrExMapper.getPageByAssociatedDiseases( wrapper);
        System.out.println("******");
        List<EtcmUiElPo> uiElName = etcmPxExMapper.getUIElName(uiTypeCode, languageCode);
        List<Map<String,String>> resultList=new ArrayList<>();
        if(sortType.equalsIgnoreCase(CommonConsts.SORT_TYPE_ASC)){
            iPage = iPage.stream().sorted(Comparator.comparing(EtcmIngrDiseasePo::getIngrDiseaseDistance)).collect(Collectors.toList());
        }else {
            iPage = iPage.stream().sorted(Comparator.comparing(EtcmIngrDiseasePo::getIngrDiseaseDistance).reversed()).collect(Collectors.toList());
        }
        List<EtcmIngrDiseasePo> collect = iPage.stream().skip((pageNo - 1) * pageSize).limit(pageSize).
                collect(Collectors.toList());

        collect.forEach(etcmIngrDiseasePo -> {
            Map<String, String> map = getStringStringMap(languageCode, etcmIngrDiseasePo, uiElName);
            resultList.add(map);
        });
        PageModel<Map<String,String>> page=new PageModel<>();
        page.setPageNo(pageNo);
        page.setPageSize(pageSize);
        page.setRecords(resultList);
        page.setTotalCount(iPage.size());
        return new ResultModel<PageModel<Map<String,String>>>().success(page);
    }

    @Override
    public ResultModel<PageModel<Map<String, String>>> getPageByPx(String languageCode, String uiTypeCode, String ingrId, Integer pageNo, Integer pageSize, String searchName,String sortType) {
        QueryWrapper<EtcmPxPo> wrapper = new QueryWrapper<>();
        wrapper.eq("t1.ingr_id", ingrId);

        if (StringUtils.isNotBlank(searchName)){
            wrapper.and(w -> w.like("t3.px_zh_name",searchName)
                    .or().like("t3.px_zh_name_abb", searchName)
                    .or().like("t3.px_zh_name_wb", searchName)
                    .or().like("t3.px_zh_name_py",searchName)
                    .or().like("t3.px_en_name", searchName)
                    .or().like("t3.px_en_name_abb", searchName)
                    .or().like("t3.px_latin_name", searchName)
                    .or().like("t3.px_latin_name_abb", searchName)
                    .or().like("t3.px_name_alias", searchName)

            );
        }
        if(sortType.equalsIgnoreCase(CommonConsts.SORT_TYPE_ASC)){
            wrapper.orderByAsc("t3.px_code");
        }else {
            wrapper.orderByDesc("t3.px_code");
        }
        IPage<EtcmPxPo> page = etcmIngrExMapper.getPageByPx(new Page<>(pageNo, pageSize), wrapper);

        List<Map<String, String>> resList = new ArrayList<>();
        for (EtcmPxPo record : page.getRecords()) {
            HashMap<String, String> map = new HashMap<>();
            List<EtcmPxExPo> exList = etcmPxExServiceInf.list(new QueryWrapper<EtcmPxExPo>()
                    .eq(EtcmPxExPo.STATUS, CommonConsts.COMMON_YES)
                    .eq(EtcmPxExPo.PX_ID, record.getPxCode())
                    .eq("language_code", languageCode)
                    .eq("ui_type_code", uiTypeCode)
            );
            for (EtcmPxExPo etcmPxExPo : exList) {
                map.put(etcmPxExPo.getUiElCode(), etcmPxExPo.getPxExCon());
            }
            resList.add(map);
        }
        PageModel<Map<String, String>> resPage = new PageModel<>();
        resPage.setPageNo(pageNo);
        resPage.setPageSize(pageSize);
        resPage.setRecords(resList);
        resPage.setTotalCount(page.getTotal());
        return new ResultModel<PageModel<Map<String, String>>>().success(resPage);
    }

    @Override
    public ResultModel<PageModel<Map<String, String>>> getPageByHerb(String languageCode, String uiTypeCode, String ingrId, Integer pageNo, Integer pageSize, String searchName ,String herbFlavorCode,String herbPropertyCode,String herbMeridiansCode, String sortType) {
        QueryWrapper<EtcmHerbPo> wrapper = new QueryWrapper<>();
        wrapper.eq("t1.ingr_code", ingrId);
        if (StringUtils.isNotBlank(herbFlavorCode)){
            wrapper.in("t4.flavor_code",herbFlavorCode.split(","));
        }

        if (StringUtils.isNotBlank(herbPropertyCode)){
            wrapper.in("t5.property_code",herbPropertyCode.split(","));
        }

        if (StringUtils.isNotBlank(herbMeridiansCode)){
            wrapper.in("t6.meridians_code",herbMeridiansCode.split(","));
        }
        if (StringUtils.isNotBlank(searchName)){
            wrapper.and(w->w.like( "t3.herb_zh_name", searchName)
                    .or().like( "t3.herb_zh_name_abb", searchName)
                    .or().like( "t3.herb_zh_name_wb", searchName)
                    .or().like( "t3.herb_zh_name_py", searchName)
                    .or().like( "t3.herb_en_name", searchName)
                    .or().like( "t3.herb_en_name_abb", searchName)
                    .or().like( "t3.herb_latin_name", searchName)
                    .or().like( "t3.herb_latin_name_abb", searchName)
                    .or().like( "t3.herb_name_alias", searchName));
        }

        if(sortType.equalsIgnoreCase(CommonConsts.SORT_TYPE_ASC)){
            wrapper.orderByAsc("t3.herb_code");
        }else {
            wrapper.orderByDesc("t3.herb_code");
        }
        wrapper.groupBy("t3.id");
        wrapper.isNotNull("t3.id");
        IPage<EtcmHerbPo> page = etcmIngrExMapper.getPageByHerb(new Page<>(pageNo, pageSize), wrapper);

        List<Map<String, String>> resList = new ArrayList<>();
        for (EtcmHerbPo record : page.getRecords()) {
            HashMap<String, String> map = new HashMap<>(16);
            List<EtcmHerbExPo> exList = etcmHerbExMapper.selectList(new QueryWrapper<EtcmHerbExPo>()
                    .eq("status", CommonConsts.COMMON_YES)
                    .eq("herb_id", record.getHerbCode())
                    .eq("language_code", languageCode)
                    .eq("ui_type_code", uiTypeCode)
            );
            for (EtcmHerbExPo etcmHerbExPo : exList) {
                map.put(etcmHerbExPo.getUiElCode(), etcmHerbExPo.getHerbExCon());
            }
            resList.add(map);
        }
        PageModel<Map<String, String>> resPage = new PageModel<>();
        resPage.setPageNo(pageNo);
        resPage.setPageSize(pageSize);
        resPage.setRecords(resList);
        resPage.setTotalCount(page.getTotal());
        return new ResultModel<PageModel<Map<String, String>>>().success(resPage);
    }

    @Override
    public ResultModel<PageModel<Map<String, String>>> getPageByTarget(String languageCode, String uiTypeCode, String ingrId, Integer pageNo, Integer pageSize, String searchName, String type, String sortType) {
        if (StringUtils.isBlank(type)){
            return new ResultModel<PageModel<Map<String, String>>>().success(new PageModel<>());
        }
        QueryWrapper<EtcmIngrPo> wrapper = new QueryWrapper<>();
        wrapper.in("t2.target_type_code",type.split(","));
        if (StringUtils.isNotBlank(searchName)) {
            wrapper.and(w->w.like("t2.target_zh_name", searchName)
                    .or().like("t2.target_zh_name_py", searchName)
                    .or().like("t2.target_zh_name_wb", searchName)
                    .or().like("t2.target_zh_name_abb", searchName)
                    .or().like("t2.target_en_name", searchName)
                    .or().like("t2.target_en_name_abb", searchName)
                    .or().like("t2.target_latin_name", searchName)
                    .or().like("t2.target_latin_name_abb", searchName)
                    .or().like("t2.target_name_alias", searchName));
        }

        wrapper.eq("t1.status", CommonConsts.COMMON_YES);
        wrapper.eq("t1.ingr_id", ingrId);
        wrapper.eq("t3.language_code", languageCode);

//        wrapper.groupBy("t1.id");
        if (sortType.equalsIgnoreCase(CommonConsts.SORT_TYPE_ASC)) {
            wrapper.orderByAsc("t1.target_id");
        } else {
            wrapper.orderByDesc("t1.target_id");
        }

        IPage<EtcmIngrTargetPo> pageTarget = etcmIngrExMapper.getPageByTarget(new Page<>(pageNo, pageSize), wrapper);

        List<Map<String, String>> resList = new ArrayList<>();

        List<EtcmUiElPo> uiElName = etcmPxExMapper.getUIElName(uiTypeCode, languageCode);
        pageTarget.getRecords().forEach(etcmIngrTargetPo -> {
            Map<String, String> map = getStringStringMap(languageCode, etcmIngrTargetPo, uiElName);
            resList.add(map);
        });
        PageModel<Map<String,String>> page=new PageModel<>();
        page.setPageNo(pageNo);
        page.setPageSize(pageSize);
        page.setRecords(resList);
        page.setTotalCount(page.getTotalCount());
        return new ResultModel<PageModel<Map<String,String>>>().success(page);
    }




    @Override
    public ResultModel<PageModel<Map<String, String>>> getPage(String languageCode, String uiTypeCode, Integer pageNo, Integer pageSize, String searchName, String sortType,String property ) {
        QueryWrapper<EtcmIngrPo> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(searchName)) {
            wrapper.and(w -> w.like("t1.ingr_zh_name", searchName)
                    .or().like("t1.ingr_zh_name_abb", searchName)
                    .or().like("t1.ingr_zh_name_wb", searchName)
                    .or().like("t1.ingr_zh_name_py", searchName)
                    .or().like("t1.ingr_en_name", searchName)
                    .or().like("t1.ingr_en_name_abb", searchName)
                    .or().like("t1.ingr_latin_name", searchName)
                    .or().like("t1.ingr_latin_name_abb", searchName)
                    .or().like("t1.ingr_name_alias", searchName));
        }

        if (StringUtils.isNotBlank(property)) {
            wrapper.eq("t3.property_code", property);
        }
        wrapper.eq("t1.status", CommonConsts.COMMON_YES);
        //wrapper.groupBy("t1.id");
        if (sortType.equalsIgnoreCase(CommonConsts.SORT_TYPE_ASC)) {
            wrapper.orderByAsc("t1.ingr_code");
        } else {
            wrapper.orderByDesc("t1.ingr_code");
        }
        IPage<EtcmIngrPo> page = null;
        if(StringUtils.isNotBlank(property)){
            page = etcmIngrExMapper.getPageByProperty(new Page<>(pageNo, pageSize), wrapper);
        }
        if(StringUtils.isBlank(property)){
            page = etcmIngrExMapper.getIngrPage(new Page<>(pageNo, pageSize), wrapper);
        }
        List<Map<String, String>> resList = new ArrayList<>();
        for (EtcmIngrPo record : page.getRecords()) {
            HashMap<String, String> map = new HashMap<>();
            List<EtcmIngrExPo> exList = etcmIngrExServiceInf.list(new QueryWrapper<EtcmIngrExPo>()
                    .eq("status", CommonConsts.COMMON_YES)
                    .eq("ingr_id", record.getIngrCode())
                    .eq("language_code", languageCode)
                    .eq("ui_type_code", uiTypeCode)
            );
            for (EtcmIngrExPo etcmIngrExPo : exList) {
                map.put(etcmIngrExPo.getUiElCode(), etcmIngrExPo.getIngrExCon());
            }
            resList.add(map);
        }
        PageModel<Map<String, String>> resPage = new PageModel<>();
        resPage.setPageNo(pageNo);
        resPage.setPageSize(pageSize);
        resPage.setRecords(resList);
        resPage.setTotalCount(page.getTotal());
        return new ResultModel<PageModel<Map<String, String>>>().success(resPage);
    }

    @Override
    public ResultModel<List<EtcmCommonBaseInfoRespVO>> getDetails(String ingrId, String languageCode, String uiTypeCode) {
        List<EtcmIngrExPo> exList = etcmIngrExMapper.getList(new QueryWrapper<EtcmIngrExPo>()
                .eq("t1.status", CommonConsts.COMMON_YES)
                .eq("t2.status", CommonConsts.COMMON_YES)
                .eq("t1.ingr_id", ingrId)
                .eq("t2.language_code", languageCode)
                .eq("t2.ui_type_code", uiTypeCode)
                .isNotNull("t1.ingr_ex_con")
                .orderByAsc("t2.ui_el_sort")
        );
        List<EtcmCommonBaseInfoRespVO> resList = new ArrayList<>();
        for (EtcmIngrExPo etcmIngrExPo : exList) {
            EtcmCommonBaseInfoRespVO respVO = new EtcmCommonBaseInfoRespVO();
            respVO.setUiElName(etcmIngrExPo.getUiElName());
            respVO.setUiElValue(etcmIngrExPo.getIngrExCon());
            resList.add(respVO);
        }
        return new ResultModel<List<EtcmCommonBaseInfoRespVO>>().success(resList);
    }

    @Override
    public ResultModel<List<EtcmCommonBaseInfoRespVO>> getAdmetDetails(String ingrId, String langCode, String uiTypeCode, Integer pageNo, Integer pageSize, String content) {

        List<EtcmIngrExPo> exPage = etcmIngrExMapper.selectList(new QueryWrapper<EtcmIngrExPo>()
                .eq("status", CommonConsts.COMMON_YES)
                .eq("ingr_id", ingrId)
                .eq("language_code", langCode)
                .eq("ui_type_code", CommonConsts.UI_TYPE_CODE_INGR)
        );
        List<EtcmUiElPo> uiElName = etcmPxExMapper.getUIElName(CommonConsts.UI_TYPE_CODE_INGR, langCode);
        uiElName = uiElName.stream().filter(s -> s.getUiElSort() > 11).sorted(Comparator.comparing(EtcmUiElPo::getUiElSort)).collect(Collectors.toList());

        List<EtcmCommonBaseInfoRespVO> resList = new ArrayList<>();
        for (EtcmIngrExPo etcmIngrExPo : exPage) {
            EtcmCommonBaseInfoRespVO respVO = new EtcmCommonBaseInfoRespVO();
            for (EtcmUiElPo etcmUiElPo : uiElName) {
                if (etcmIngrExPo.getUiElCode().equals(etcmUiElPo.getUiElCode())){
                    respVO.setUiElName(etcmIngrExPo.getUiElCode());
                    respVO.setUiElValue(etcmIngrExPo.getIngrExCon());
                    resList.add(respVO);
                }
            }


        }

        return new ResultModel<List<EtcmCommonBaseInfoRespVO>>().success(resList);
    }

    @Override
    public ResultModel<Map<String, String>> getStatistics(String content) {
        QueryWrapper<String> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(content)){
            wrapper.and(w -> w.like("t1.ingr_zh_name", content)
                    .or().like("t1.ingr_zh_name_abb", content)
                    .or().like("t1.ingr_zh_name_wb", content)
                    .or().like("t1.ingr_zh_name_py", content)
                    .or().like("t1.ingr_en_name", content)
                    .or().like("t1.ingr_en_name_abb", content)
                    .or().like("t1.ingr_latin_name", content)
                    .or().like("t1.ingr_latin_name_abb", content)
                    .or().like("t1.ingr_name_alias", content));
        }

        List<String> list = etcmIngrExMapper.getStatistics(wrapper);
        Map<String, Long> map = list.stream().filter(StringUtils::isNotBlank).collect(Collectors.groupingBy(s -> s,Collectors.counting()));
        long count = list.stream().filter(StringUtils::isNotBlank).count();
        Map<String, String> res = getStatistics(count, map);
        return new ResultModel<Map<String, String>>().success(res);
    }

    @Override
    public ResultModel<Map<String, String>> getTargetStatistics(String content, String ingrId) {
        QueryWrapper<EtcmTargetPo> wrapper=new QueryWrapper<>();
        wrapper.eq("t1.ingr_id", ingrId);
        if(com.newviews.tcmip.common.utils.StringUtils.isNotBlank(content)){
            wrapper.and(w->w.like("t2.target_zh_name", content)
                    .or().like("t2.target_zh_name_py", content)
                    .or().like("t2.target_zh_name_wb", content)
                    .or().like("t2.target_zh_name_abb", content)
                    .or().like("t2.target_en_name", content)
                    .or().like("t2.target_en_name_abb", content)
                    .or().like("t2.target_latin_name", content)
                    .or().like("t2.target_latin_name_abb", content)
                    .or().like("t2.target_name_alias", content));
        }

        // wrapper.isNotNull("t2.id");
        List<EtcmTargetPo> list = etcmIngrExMapper.getTargetList( wrapper);
        Map<String, Long> map = list.stream().map(EtcmTargetPo::getTargetTypeCode).filter(Objects::nonNull).collect(Collectors.groupingBy(s -> s,Collectors.counting()));
        long count = list.stream().map(EtcmTargetPo::getTargetTypeCode).filter(Objects::nonNull).count();
        Map<String, String> res = getStatistics(count, map);
        return new ResultModel<Map<String, String>>().success(res);
    }

    @Override
    public ResultModel<EtcmVolcanoMapRespVo> getVolcanoMap(String erId) {
        List<EtcmVolcanoMapVo> res = etcmIngrExMapper.getVolcanoMap(erId);
        EtcmVolcanoMapRespVo respVo = new EtcmVolcanoMapRespVo();
        List<List<String>> dataDown = new ArrayList<>();
        List<List<String>> dataNotSignificant = new ArrayList<>();
        List<List<String>> dataUp = new ArrayList<>();
        for (EtcmVolcanoMapVo etcmVolcanoMapVo : res) {
            List<String> data = new ArrayList<>();
            if (CombinConsts.UP.equalsIgnoreCase(etcmVolcanoMapVo.getSignificance())){
                data.add(etcmVolcanoMapVo.getLogFc());
                data.add(etcmVolcanoMapVo.getName());
                data.add(etcmVolcanoMapVo.getGenesymbol());
                dataUp.add(data);
            }
            if (CombinConsts.DOWN.equalsIgnoreCase(etcmVolcanoMapVo.getSignificance())){
                data.add(etcmVolcanoMapVo.getLogFc());
                data.add(etcmVolcanoMapVo.getName());
                data.add(etcmVolcanoMapVo.getGenesymbol());
                dataDown.add(data);
            }
            if (CombinConsts.NOT_SIGNIFICANT.equalsIgnoreCase(etcmVolcanoMapVo.getSignificance())){
                data.add(etcmVolcanoMapVo.getLogFc());
                data.add(etcmVolcanoMapVo.getName());
                data.add(etcmVolcanoMapVo.getGenesymbol());
                dataNotSignificant.add(data);
            }


        }
        respVo.setDataDown(dataDown);
        respVo.setDataNotSignificant(dataNotSignificant);
        respVo.setDataUp(dataUp);
        return new ResultModel<EtcmVolcanoMapRespVo>().success(respVo);
    }



    @Override
    public ResultModel<EtcmScatterDiagramRespVo> getScatterDiagram(String erId) {
        List<EtcmScatterDiagramVo> resBp = etcmIngrExMapper.getScatterDiagramBp(erId);
        List<EtcmScatterDiagramVo> resCc = etcmIngrExMapper.getScatterDiagramCc(erId);
        List<EtcmScatterDiagramVo> resMf = etcmIngrExMapper.getScatterDiagramMf(erId);

        //List<EtcmScatterDiagramVo> scatterDiagram = etcmIngrExMapper.getScatterDiagram(erId);

        EtcmScatterDiagramRespVo respVo = new EtcmScatterDiagramRespVo();

//        List<List<String>> dataBp = new ArrayList<>();
//        List<List<String>> dataCc = new ArrayList<>();
//        List<List<String>> dataMf = new ArrayList<>();
//        for (EtcmScatterDiagramVo etcmScatterDiagramVo : scatterDiagram) {
//            List<String> data = new ArrayList<>();
//            String geneRatio = etcmScatterDiagramVo.getGeneRatio();
//            String[] split = geneRatio.split("/");
//            double numberOne = Double.parseDouble(split[0]);
//            double numberTwo = Double.parseDouble(split[1]);
//            double resNumber = numberOne / numberTwo;
//            if (etcmScatterDiagramVo.getOntology().equalsIgnoreCase(CombinConsts.BP)){
//                data.add(String.valueOf(resNumber));
//                data.add(etcmScatterDiagramVo.getDescription());
//                data.add(etcmScatterDiagramVo.getCount());
//                data.add(etcmScatterDiagramVo.getPAdjust());
//                dataBp.add(data);
//            }
//            if (etcmScatterDiagramVo.getOntology().equalsIgnoreCase(CombinConsts.CC)){
//                data.add(String.valueOf(resNumber));
//                data.add(etcmScatterDiagramVo.getDescription());
//                data.add(etcmScatterDiagramVo.getCount());
//                data.add(etcmScatterDiagramVo.getPAdjust());
//                dataCc.add(data);
//            }
//            if (etcmScatterDiagramVo.getOntology().equalsIgnoreCase(CombinConsts.MF)){
//                data.add(String.valueOf(resNumber));
//                data.add(etcmScatterDiagramVo.getDescription());
//                data.add(etcmScatterDiagramVo.getCount());
//                data.add(etcmScatterDiagramVo.getPAdjust());
//                dataMf.add(data);
//            }
//
//        }
        List<List<String>> dataBp = extracted(resBp);
        List<List<String>> dataCc = extracted(resCc);
        List<List<String>> dataMf = extracted(resMf);
        respVo.setDataBp(dataBp);
        respVo.setDataCc(dataCc);
        respVo.setDataMf(dataMf);
        return new ResultModel<EtcmScatterDiagramRespVo>().success(respVo);
    }

    private static List<List<String>> extracted(List<EtcmScatterDiagramVo> resBp) {
        List<List<String>> dataRes = new ArrayList<>();
        for (EtcmScatterDiagramVo etcmScatterDiagramVo : resBp) {
            List<String> data = new ArrayList<>();
            String geneRatio = etcmScatterDiagramVo.getGeneRatio();
            String[] split = geneRatio.split("/");
            double numberOne = Double.parseDouble(split[0]);
            double numberTwo = Double.parseDouble(split[1]);
            double resNumber = numberOne / numberTwo;
            if (etcmScatterDiagramVo.getOntology().equalsIgnoreCase(CombinConsts.BP)){

            }
            data.add(String.valueOf(resNumber));
            data.add(etcmScatterDiagramVo.getDescription());
            data.add(etcmScatterDiagramVo.getCount());
            data.add(etcmScatterDiagramVo.getPAdjust());
            dataRes.add(data);
        }
        return dataRes;
    }

    @Override
    public ResultModel<EtcmBarChartRespVo> getBarChart(String erId) {
        List<EtcmBarChartVo> res = etcmIngrExMapper.getBarChart(erId);
        EtcmBarChartRespVo respVo = new EtcmBarChartRespVo();
        List<List<String>> dataRes = new ArrayList<>();
        if(!CollectionUtils.isEmpty(res)){
            List<String> listFirst = new ArrayList<>();
            listFirst.add("p.adjust");
            listFirst.add("Count");
            listFirst.add("Description");
            dataRes.add(listFirst);
        }


        for (EtcmBarChartVo re : res) {
            List<String> data = new ArrayList<>();
            data.add(re.getPAdjust());
            data.add(re.getCount());
            data.add(re.getDescription());
            dataRes.add(data);
        }
        respVo.setData(dataRes);
        return new ResultModel<EtcmBarChartRespVo>().success(respVo);
    }

    private Map<String, String> getStatistics(Long totalNumber,Map<String, Long> map){
        Map<String,String> mapRes = new HashMap<>(16);
        map.keySet().forEach(s -> {
            BigDecimal totalCount = new BigDecimal(totalNumber);
            BigDecimal size = new BigDecimal(map.get(s));
            BigDecimal bigDecimal = size.divide(totalCount,2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
            mapRes.put(s,bigDecimal.toString());
        });
        return mapRes;
    }

    private static Map<String, String> getStringStringMap(String langCode, EtcmExperimentalRecordsIngrPo recordsIngrPo, List<EtcmUiElPo> uiElNameList) {
        Map<String,String> map = new HashMap<>(16);
        for (EtcmUiElPo etcmUiElPo : uiElNameList) {
            switch (etcmUiElPo.getUiElSort()){
                case 1:
                    map.put(etcmUiElPo.getUiElCode(), recordsIngrPo.getErId());
                    break;
                case 2:
                    if (CommonConsts.LANG_CODE_ENG.equals(langCode)){
                        map.put(etcmUiElPo.getUiElCode(), recordsIngrPo.getErEnName());
                    }
                    if (CommonConsts.LANG_CODE_CHN.equals(langCode)){
                        map.put(etcmUiElPo.getUiElCode(), recordsIngrPo.getErZhName());
                    }
                    break;
                case 3:
                    map.put(etcmUiElPo.getUiElCode(), recordsIngrPo.getPubchemCid());
                    break;
                case 5:
                    map.put(etcmUiElPo.getUiElCode(), recordsIngrPo.getMolecularFormula());
                    break;
                case 6:
                    map.put(etcmUiElPo.getUiElCode(), recordsIngrPo.getMolecularWeight());
                    break;
                case 7:
                    map.put(etcmUiElPo.getUiElCode(), recordsIngrPo.getConcentration());
                    break;
                case 8:
                    map.put(etcmUiElPo.getUiElCode(),recordsIngrPo.getCelllines());
                    break;
                case 9:
                    map.put(etcmUiElPo.getUiElCode(),recordsIngrPo.getOrangism());
                default:
                    map.put(UiElCodeEnums.IS_MAP.getUiElCode(),recordsIngrPo.getIsMap());
            }

        }
        return map;
    }
    private static Map<String, String> getStringStringMap(String langCode, EtcmIngrTargetPo etcmIngrTargetPo, List<EtcmUiElPo> uiElNameList) {
        Map<String,String> map = new HashMap<>(16);
        for (EtcmUiElPo etcmUiElPo : uiElNameList) {
            switch (etcmUiElPo.getUiElSort()){
                case 1:
                    map.put(etcmUiElPo.getUiElCode(), etcmIngrTargetPo.getTargetId());
                    break;
                case 3:
                    map.put(etcmUiElPo.getUiElCode(), etcmIngrTargetPo.getSymbolIdHum());
                    break;

                case 4:
                    map.put(etcmUiElPo.getUiElCode(), etcmIngrTargetPo.getTypeName());
                    break;
                case 6:
                    map.put(etcmUiElPo.getUiElCode(), etcmIngrTargetPo.getEntrezIdHum());
                    break;
                case 7:
                    map.put(etcmUiElPo.getUiElCode(),etcmIngrTargetPo.getUniprotIdHum());
                default:
            }

        }
        return map;
    }

    private static Map<String, String> getStringStringMap(String langCode, EtcmIngrDiseasePo etcmIngrDiseasePo, List<EtcmUiElPo> uiElNameList) {
        Map<String,String> map = new HashMap<>(16);
        for (EtcmUiElPo etcmUiElPo : uiElNameList) {
            switch (etcmUiElPo.getUiElSort()){
                case 1:
                    map.put(etcmUiElPo.getUiElCode(), etcmIngrDiseasePo.getIngrId() + "-" + etcmIngrDiseasePo.getDiseaseId());
                    break;
                case 2:
                    if (CommonConsts.LANG_CODE_ENG.equals(langCode)){
                        map.put(etcmUiElPo.getUiElCode(), etcmIngrDiseasePo.getIngrEnName());
                    }
                    if (CommonConsts.LANG_CODE_CHN.equals(langCode)){
                        map.put(etcmUiElPo.getUiElCode(), etcmIngrDiseasePo.getIngrZhName());
                    }
                    break;

                case 3:
                    if (CommonConsts.LANG_CODE_ENG.equals(langCode)){
                        map.put(etcmUiElPo.getUiElCode(), etcmIngrDiseasePo.getDiseaseEnName());
                    }
                    if (CommonConsts.LANG_CODE_CHN.equals(langCode)){
                        map.put(etcmUiElPo.getUiElCode(), etcmIngrDiseasePo.getDiseaseZhName());
                    }
                    break;
                case 4:
                    map.put(etcmUiElPo.getUiElCode(), etcmIngrDiseasePo.getIngrDiseaseDistance());
                    break;
                case 5:
                    map.put(etcmUiElPo.getUiElCode(),etcmIngrDiseasePo.getPValue());
                default:
            }

        }
        return map;
    }

    private static Map<String, String> getStringStringMap(String langCode, EtcmIngrIngrPo etcmIngrIngrPo, List<EtcmUiElPo> uiElNameList) {
        Map<String,String> map = new HashMap<>(16);
        for (EtcmUiElPo etcmUiElPo : uiElNameList) {
            switch (etcmUiElPo.getUiElSort()){
                case 1:
                    map.put(etcmUiElPo.getUiElCode(), etcmIngrIngrPo.getIngrCode() + "-" + etcmIngrIngrPo.getTargetIngrCode());
                    break;
                case 2:
                    if (CommonConsts.LANG_CODE_ENG.equals(langCode)){
                        map.put(etcmUiElPo.getUiElCode(), etcmIngrIngrPo.getIngrEnName());
                    }
                    if (CommonConsts.LANG_CODE_CHN.equals(langCode)){
                        map.put(etcmUiElPo.getUiElCode(), etcmIngrIngrPo.getIngrZhName());
                    }
                    break;

                case 3:
                    if (CommonConsts.LANG_CODE_ENG.equals(langCode)){
                        map.put(etcmUiElPo.getUiElCode(), etcmIngrIngrPo.getTargetIngrEnName());
                    }
                    if (CommonConsts.LANG_CODE_CHN.equals(langCode)){
                        map.put(etcmUiElPo.getUiElCode(), etcmIngrIngrPo.getTargetIngrZhName());
                    }
                    break;
                case 4:
                    map.put(etcmUiElPo.getUiElCode(), etcmIngrIngrPo.getIngrIngrDistance());
                    break;
                case 5:
                    map.put(etcmUiElPo.getUiElCode(),etcmIngrIngrPo.getPValue());
                default:
            }

        }
        return map;
    }
}
